View Javadoc
1 /* 2 * Scope: a generic MVC framework. 3 * Copyright (c) 2000-2002, The Scope team 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name "Scope" nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * 36 * $Id: STableModel.java,v 1.12 2002/09/05 15:41:49 ludovicc Exp $ 37 */ 38 package org.scopemvc.view.swing; 39 40 41 import java.util.EventListener; 42 import javax.swing.JTable; 43 import javax.swing.event.ListDataListener; 44 import javax.swing.event.TableModelEvent; 45 import javax.swing.event.TableModelListener; 46 import javax.swing.table.TableModel; 47 import org.apache.commons.logging.Log; 48 import org.apache.commons.logging.LogFactory; 49 import org.scopemvc.core.PropertyManager; 50 import org.scopemvc.core.Selector; 51 52 /*** 53 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 54 * @author <A HREF="mailto:daniel.michalik@autel.cz">Daniel Michalik</A> 55 * @created 05 September 2002 56 * @version $Revision: 1.12 $ $Date: 2002/09/05 15:41:49 $ 57 * @see STable 58 */ 59 public class STableModel extends SAbstractListModel 60 implements TableModel { 61 62 private final static Log LOG = LogFactory.getLog(STableModel.class); 63 64 /*** 65 * TODO: describe of the Field 66 */ 67 protected Selector[] columnSelectors; 68 /*** 69 * TODO: describe of the Field 70 */ 71 protected String[] columnNames; 72 /*** 73 * if null editable when read-write property else read-only 74 */ 75 protected boolean[] columnsEditable; 76 // 77 78 /*** 79 * TODO: describe of the Field 80 */ 81 protected PropertyManager manager; 82 83 /*** 84 * TODO: describe of the Field 85 */ 86 protected JTable table; 87 88 89 /*** 90 * Constructor for the STableModel object 91 * 92 * @param inTable TODO: Describe the Parameter 93 */ 94 public STableModel(JTable inTable) { 95 if (inTable == null) { 96 throw new IllegalArgumentException("Create model for a parent JTable, not null"); 97 } 98 table = inTable; 99 } 100 101 102 // --------------------- implement TableModel --------------------------- 103 104 /*** 105 * Gets the row count 106 * 107 * @return The rowCount value 108 */ 109 public int getRowCount() { 110 if (LOG.isDebugEnabled()) { 111 LOG.debug("getRowCount: " + getSize()); 112 } 113 return getSize(); 114 } 115 116 117 /*** 118 * Gets the column count 119 * 120 * @return The columnCount value 121 */ 122 public int getColumnCount() { 123 if (columnSelectors == null) { 124 if (LOG.isDebugEnabled()) { 125 LOG.debug("getRowCount: 0"); 126 } 127 return 0; 128 } 129 if (LOG.isDebugEnabled()) { 130 LOG.debug("getColumnCount: " + columnSelectors.length); 131 } 132 return columnSelectors.length; 133 } 134 135 136 /*** 137 * Gets the column name 138 * 139 * @param inColumn TODO: Describe the Parameter 140 * @return The columnName value 141 */ 142 public String getColumnName(int inColumn) { 143 if (columnNames == null || inColumn >= columnNames.length) { 144 return String.valueOf((char) ('A' + inColumn)); 145 } 146 return columnNames[inColumn]; 147 } 148 149 150 /*** 151 * Gets the column class 152 * 153 * @param inColumn TODO: Describe the Parameter 154 * @return The columnClass value 155 */ 156 public Class getColumnClass(int inColumn) { 157 PropertyManager manager = getManager(); 158 Object row = getElementAt(0); 159 Selector selector = getColumnSelector(inColumn); 160 if (manager == null || row == null || selector == null) { 161 LOG.warn("getColumnClass: no manager or row or selector"); 162 return Object.class; 163 } 164 165 try { 166 if (LOG.isDebugEnabled()) { 167 LOG.debug("getColumnClass: " + manager.getPropertyClass(row, selector)); 168 } 169 return manager.getPropertyClass(row, selector); 170 } catch (Exception e) { 171 LOG.warn("getColumnClass: can't get class for " + inColumn, e); 172 } 173 return Object.class; 174 } 175 176 177 /*** 178 * Gets the cell editable 179 * 180 * @param inRow TODO: Describe the Parameter 181 * @param inColumn TODO: Describe the Parameter 182 * @return The cellEditable value 183 */ 184 public boolean isCellEditable(int inRow, int inColumn) { 185 if (columnsEditable != null && inColumn < columnsEditable.length) { 186 return columnsEditable[inColumn]; 187 } 188 189 Object row = getElementAt(inRow); 190 PropertyManager manager = getManager(); 191 Selector selector = getColumnSelector(inColumn); 192 if (manager == null || row == null || selector == null) { 193 LOG.warn("isCellEditable: no manager or row or selector"); 194 return false; 195 } 196 197 try { 198 if (LOG.isDebugEnabled()) { 199 LOG.debug("isCellEditable: " + (!manager.isReadOnly(row, selector))); 200 } 201 return (!manager.isReadOnly(row, selector)); 202 } catch (Exception ex) { 203 LOG.warn("isCellEditable(" + inRow + "," + inColumn + "): Unable " 204 + "to find out if cell is editable. Return false.", ex); 205 } 206 return false; 207 } 208 209 210 /*** 211 * Gets the value at 212 * 213 * @param inRow TODO: Describe the Parameter 214 * @param inColumn TODO: Describe the Parameter 215 * @return The valueAt value 216 */ 217 public Object getValueAt(int inRow, int inColumn) { 218 Object row = getElementAt(inRow); 219 Selector selector = getColumnSelector(inColumn); 220 PropertyManager manager = getPropertyManager(); 221 if (manager == null || row == null || selector == null) { 222 LOG.warn("isCellEditable: no manager or row or selector"); 223 return null; 224 } 225 try { 226 if (LOG.isDebugEnabled()) { 227 LOG.debug("getValueAt: " + manager.get(row, selector) + "(" + manager.get(row, selector).getClass() + ")"); 228 } 229 return manager.get(row, selector); 230 } catch (Exception e) { 231 LOG.warn("Can't get column " + inColumn + " from row " + inRow, e); 232 } 233 return null; 234 } 235 236 /*** 237 * Returns an array of all the listeners of the given type that were added 238 * to this model. 239 * 240 * @param listenerType TODO: Describe the Parameter 241 * @return The listeners value 242 * @returns all of the objects receiving <code>listenerType</code> 243 * notifications from this model 244 */ 245 public EventListener[] getListeners(Class listenerType) { 246 return listenerList.getListeners(listenerType); 247 } 248 249 250 // ------------- public API ------------------- 251 252 /*** 253 * Sets the column selectors 254 * 255 * @param inSelectors The new columnSelectors value 256 */ 257 public void setColumnSelectors(Selector[] inSelectors) { 258 columnSelectors = inSelectors; 259 } 260 261 262 /*** 263 * Sets the column selector strings 264 * 265 * @param inSelectorStrings The new columnSelectorStrings value 266 */ 267 public void setColumnSelectorStrings(String[] inSelectorStrings) { 268 if (inSelectorStrings == null) { 269 columnSelectors = null; 270 } 271 columnSelectors = new Selector[inSelectorStrings.length]; 272 for (int i = 0; i < inSelectorStrings.length; i++) { 273 if (inSelectorStrings[i] == null) { 274 throw new IllegalArgumentException("Can't create column for null Selector"); 275 } 276 columnSelectors[i] = Selector.fromString(inSelectorStrings[i]); 277 } 278 } 279 280 281 /*** 282 * Sets the column names 283 * 284 * @param inNames The new columnNames value 285 */ 286 public void setColumnNames(String[] inNames) { 287 columnNames = inNames; 288 } 289 290 291 /*** 292 * Sets the editable columns 293 * 294 * @param inEditables The new editableColumns value 295 */ 296 public void setEditableColumns(boolean[] inEditables) { 297 columnsEditable = inEditables; 298 } 299 300 301 /*** 302 * Sets the value at 303 * 304 * @param inValue The new valueAt value 305 * @param inRow The new valueAt value 306 * @param inColumn The new valueAt value 307 */ 308 public void setValueAt(Object inValue, int inRow, int inColumn) { 309 Object row = getElementAt(inRow); 310 Selector selector = getColumnSelector(inColumn); 311 PropertyManager manager = getPropertyManager(); 312 if (manager == null || row == null || selector == null) { 313 LOG.warn("setValueAt: no manager or row or selector"); 314 } 315 try { 316 manager.set(row, selector, inValue); 317 } catch (Exception e) { 318 LOG.warn("Can't set column " + inColumn + " from row " + inRow, e); 319 } 320 } 321 322 323 // ------ Override ListDataListener stuff to forward to TableModelListener ------ 324 325 /*** 326 * Adds an element to the ListDataListener attribute of the STableModel 327 * object 328 * 329 * @param l The element to be added to the ListDataListener attribute 330 */ 331 public void addListDataListener(ListDataListener l) { 332 throw new UnsupportedOperationException("Can't add ListDataListener to STableModel"); 333 } 334 335 336 /*** 337 * TODO: document the method 338 * 339 * @param l TODO: Describe the Parameter 340 */ 341 public void removeListDataListener(ListDataListener l) { 342 throw new UnsupportedOperationException("Can't remove ListDataListener from STableModel"); 343 } 344 345 346 // ------- TableModelListeners copied from JDK1.3.1 AbstractTableModel ------- 347 348 /*** 349 * Adds a listener to the list that's notified each time a change to the 350 * data model occurs. 351 * 352 * @param l the TableModelListener 353 */ 354 public void addTableModelListener(TableModelListener l) { 355 listenerList.add(TableModelListener.class, l); 356 } 357 358 /*** 359 * Removes a listener from the list that's notified each time a change to 360 * the data model occurs. 361 * 362 * @param l the TableModelListener 363 */ 364 public void removeTableModelListener(TableModelListener l) { 365 listenerList.remove(TableModelListener.class, l); 366 } 367 368 /*** 369 * Notifies all listeners that all cell values in the table's rows may have 370 * changed. The number of rows may also have changed and the <code>JTable</code> 371 * should redraw the table from scratch. The structure of the table (as in 372 * the order of the columns) is assumed to be the same. 373 * 374 * @see TableModelEvent 375 */ 376 public void fireTableDataChanged() { 377 fireTableChanged(new TableModelEvent(this)); 378 } 379 380 /*** 381 * Notifies all listeners that the table's structure has changed. The number 382 * of columns in the table, and the names and types of the new columns may 383 * be different from the previous state. If the <code>JTable</code> receives 384 * this event and its <code>autoCreateColumnsFromModel</code> flag is set it 385 * discards any table columns that it had and reallocates default columns in 386 * the order they appear in the model. This is the same as calling <code>setModel(TableModel)</code> 387 * on the <code>JTable</code>. 388 * 389 * @see TableModelEvent 390 */ 391 public void fireTableStructureChanged() { 392 fireTableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW)); 393 } 394 395 /*** 396 * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code> 397 * , inclusive, have been inserted. 398 * 399 * @param firstRow the first row 400 * @param lastRow the last row 401 * @see TableModelEvent 402 */ 403 public void fireTableRowsInserted(int firstRow, int lastRow) { 404 fireTableChanged( 405 new TableModelEvent( 406 this, 407 firstRow, 408 lastRow, 409 TableModelEvent.ALL_COLUMNS, 410 TableModelEvent.INSERT)); 411 } 412 413 /*** 414 * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code> 415 * , inclusive, have been updated. 416 * 417 * @param firstRow the first row 418 * @param lastRow the last row 419 * @see TableModelEvent 420 */ 421 public void fireTableRowsUpdated(int firstRow, int lastRow) { 422 fireTableChanged( 423 new TableModelEvent( 424 this, 425 firstRow, 426 lastRow, 427 TableModelEvent.ALL_COLUMNS, 428 TableModelEvent.UPDATE)); 429 } 430 431 /*** 432 * Notifies all listeners that rows in the range <code>[firstRow, lastRow]</code> 433 * , inclusive, have been deleted. 434 * 435 * @param firstRow the first row 436 * @param lastRow the last row 437 * @see TableModelEvent 438 */ 439 public void fireTableRowsDeleted(int firstRow, int lastRow) { 440 fireTableChanged( 441 new TableModelEvent( 442 this, 443 firstRow, 444 lastRow, 445 TableModelEvent.ALL_COLUMNS, 446 TableModelEvent.DELETE)); 447 } 448 449 /*** 450 * Notifies all listeners that the value of the cell at <code>[row, column]</code> 451 * has been updated. 452 * 453 * @param row row of cell which has been updated 454 * @param column column of cell which has been updated 455 * @see TableModelEvent 456 */ 457 public void fireTableCellUpdated(int row, int column) { 458 fireTableChanged(new TableModelEvent(this, row, row, column)); 459 } 460 461 /*** 462 * Forwards the given notification event to all <code>TableModelListeners</code> 463 * that registered themselves as listeners for this table model. 464 * 465 * @param e the event to be forwarded 466 * @see #addTableModelListener 467 * @see TableModelEvent 468 */ 469 public void fireTableChanged(TableModelEvent e) { 470 // Guaranteed to return a non-null array 471 Object[] listeners = listenerList.getListenerList(); 472 // Process the listeners last to first, notifying 473 // those that are interested in this event 474 for (int i = listeners.length - 2; i >= 0; i -= 2) { 475 if (listeners[i] == TableModelListener.class) { 476 ((TableModelListener) listeners[i + 1]).tableChanged(e); 477 } 478 } 479 } 480 481 482 // -------------- internal ----------------- 483 484 /*** 485 * Gets the column selector 486 * 487 * @param inColumn TODO: Describe the Parameter 488 * @return The columnSelector value 489 */ 490 protected Selector getColumnSelector(int inColumn) { 491 if (columnSelectors == null) { 492 return null; 493 } 494 return columnSelectors[inColumn]; 495 } 496 497 498 /*** 499 * Gets the property manager 500 * 501 * @return The propertyManager value 502 */ 503 protected PropertyManager getPropertyManager() { 504 if (manager != null) { 505 return manager; 506 } 507 508 if (getRowCount() < 1) { 509 return null; 510 } 511 512 Object row = getElementAt(0); 513 manager = PropertyManager.getInstance(row); 514 return manager; 515 } 516 517 518 // ---------------- Bound model stuff ------------------ 519 520 /*** 521 * Called internally from updateFromProperty(). 522 * 523 * @param inModel The new shownModel value 524 */ 525 protected void setShownModel(Object inModel) { 526 527 super.setShownModel(inModel); 528 529 // if (table instanceof STable) { 530 // ((STable)table).createDefaultColumnsFromModel(); 531 // } 532 533 // ***** This is necessary for updates to work at all... 534 // ... but it looks very wrong. 535 fireTableDataChanged(); 536 537 manager = null; 538 539 // ***** This is broken because of the above hack 540 if (table instanceof STable) { 541 ((STable) table).refreshSelection(); 542 } else { 543 // Could use a better strategy for completeness 544 table.clearSelection(); 545 } 546 } 547 548 549 /*** 550 * TODO: document the method 551 * 552 * @param source TODO: Describe the Parameter 553 * @param index0 TODO: Describe the Parameter 554 * @param index1 TODO: Describe the Parameter 555 */ 556 protected void fireContentsChanged(Object source, int index0, int index1) { 557 fireTableRowsUpdated(index0, index1); 558 } 559 560 561 /*** 562 * TODO: document the method 563 * 564 * @param source TODO: Describe the Parameter 565 * @param index0 TODO: Describe the Parameter 566 * @param index1 TODO: Describe the Parameter 567 */ 568 protected void fireIntervalAdded(Object source, int index0, int index1) { 569 fireTableRowsInserted(index0, index1); 570 } 571 572 573 /*** 574 * TODO: document the method 575 * 576 * @param source TODO: Describe the Parameter 577 * @param index0 TODO: Describe the Parameter 578 * @param index1 TODO: Describe the Parameter 579 */ 580 protected void fireIntervalRemoved(Object source, int index0, int index1) { 581 fireTableRowsDeleted(index0, index1); 582 } 583 }

This page was automatically generated by Maven